package com.geoai.uimap

import android.os.Bundle
import android.util.Log
import android.view.MotionEvent
import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope
import com.alibaba.android.arouter.facade.annotation.Route
import com.geoai.basiclib.base.fragment.BaseVVDFragment
import com.geoai.basiclib.ext.SP
import com.geoai.modservice.di.ARouterPath
import com.geoai.modservice.di.eventbus.CenterToDroneLocation
import com.geoai.modservice.di.eventbus.CenterToLastLocation
import com.geoai.modservice.di.eventbus.ChangeMapSource
import com.geoai.modservice.di.eventbus.LockCameraByDroneLocation
import com.geoai.modservice.di.eventbus.ToggleMapSize
import com.geoai.modservice.di.eventbus.ToggleSize
import com.geoai.modservice.di.sp.MapControlConstants
import com.geoai.modservice.di.sp.MapControlConstants.Companion.MAP_SOURCE_KEY
import com.geoai.uimap.api.GEOMapListener
import com.geoai.uimap.api.GEOMapManagerImpl
import com.geoai.uimap.api.GEOMapMarker
import com.geoai.uimap.api.GEOMapPolyline
import com.geoai.uimap.config.MapProvider
import com.geoai.uimap.core.geomap.GEOMapMarkerImpl
import com.geoai.uimap.core.geomap.GEOMapPolylineImpl
import com.geoai.uimap.databinding.FragmentUiMapviewBinding
import com.geoai.uimap.model.GEOLatLng
import com.geoai.uimap.mvi.eis.MapViewEffect
import com.geoai.uimap.mvi.eis.MapViewIntent
import com.geoai.uimap.mvi.eis.MapViewState
import com.geoai.uimap.mvi.vm.GeoaiMapViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import kotlin.math.abs

/**
 * @Author      : Ronny
 * @Email       : Ronny_xie@hotmail.com
 * @Date        : on 2024-04-02 16:07.
 * @Description :
 */
@Route(path = ARouterPath.PATH_PAGE_MAPVIEW)
class GeoaiMapFragment: BaseVVDFragment<GeoaiMapViewModel, FragmentUiMapviewBinding>() {

    //飞机坐标
    private var mAircraftPointMarker: GEOMapMarker? = null

    //返航坐标
    private var mAircraftReturnMarker: GEOMapMarker? = null

    //飞机轨迹线
    private var mAircraftTrackPolyline: GEOMapPolyline? = null

    private val geoaiMapManagerImpl: GEOMapManagerImpl by lazy { GEOMapManagerImpl() }

    override fun hasRegisterEventBus(): Boolean = true

    override fun init(savedInstanceState: Bundle?) {

        geoaiMapManagerImpl.also {
            //初始化地图框架
            it.init(requireContext(), MapProvider.MAP_BOX, null, SP().getInt(MAP_SOURCE_KEY, 1))
            it.getMap()?.let { imap ->
                //将地图框架和view绑定
                imap.getMapView().let { map ->
                    map.parent?.let { mp -> (mp as ViewGroup).removeView(map)  }
                    mBinding.flMapLayout.addView(map)
                }
                //初始化地图定位逻辑
                imap.setOnMapLoadedListener(object : GEOMapListener.OnMapLoadedListener{
                    override fun onMapLoaded() {
                        imap.initMapLocation(R.mipmap.ic_mark_person, true)
                    }
                })
                //初始化地图触摸逻辑
                imap.addOnMapTouchListener(object : GEOMapListener.OnMapTouchListener{
                    fun isTouchSlop(motionEvent: MotionEvent): Boolean {
                        return abs(motionEvent.x - mViewModel.mapTouchPosition.first) < 20 && abs(motionEvent.y - mViewModel.mapTouchPosition.second) < 20
                    }
                    override fun onTouch(event: MotionEvent) {
                        when (event.action) {
                            MotionEvent.ACTION_DOWN -> mViewModel.mapTouchPosition = Pair(event.x.toInt(), event.y.toInt())
                            MotionEvent.ACTION_UP -> { if (isTouchSlop(event)) mViewModel.sendUiIntent(MapViewIntent.OnMapTouchEvent) }
                        }
                    }
                })
                //初始化地图点击逻辑
                imap.setOnMapClickListener(object : GEOMapListener.OnMapClickListener{
                    override fun onMapClick(var1: GEOLatLng) {
                        mViewModel.sendUiIntent(MapViewIntent.OnMapClickEvent(var1))
                    }
                })
            }
        }
    }

    override fun startObserve() {
        super.startObserve()

        lifecycleScope.launch(Dispatchers.Main) {
            mViewModel.uiEffectFlow.collect { effect ->
                when (effect) {
                    is MapViewEffect.CenterAtTargetLocation -> {
                        geoaiMapManagerImpl.getMap()?.getMapCamera()?.setPosition(effect.location)
                    }

                    is MapViewEffect.UpdateAircraftMarker -> {
                        mAircraftPointMarker = mAircraftPointMarker?.let {
                            it.setPosition(effect.location)
                            it.setRotateAngle(effect.rotate)
                        } ?: run {
                            geoaiMapManagerImpl.getMap()?.let { map ->
                                //首次定位，默认使用16级缩放
                                map.getMapCamera().setPosition(effect.location, 16.0f)

                                GEOMapMarkerImpl(map)
                                    .setPosition(effect.location)
                                    .setImageId(R.mipmap.ic_mark_uav)
                                    .setRotateAngle(effect.rotate)
                                    .period(10000)
                                    .setToTop(true)
                                    .show()
                            }
                        }
                    }

                    is MapViewEffect.UpdateAircraftReturnMarker -> {
                        mAircraftReturnMarker = mAircraftReturnMarker?.setPosition(effect.location)
                            ?: run {
                            geoaiMapManagerImpl.getMap()?.let { map ->
                                GEOMapMarkerImpl(map)
                                    .setPosition(effect.location)
                                    .setImageId(R.mipmap.ic_mark_home)
                                    .show()
                            }
                        }
                    }

                    is MapViewEffect.UpdateAircraftTrackPolyline -> {
                        mAircraftTrackPolyline = mAircraftTrackPolyline?.setPositions(effect.points)
                            ?: run {
                            geoaiMapManagerImpl.getMap()?.let { map ->
                                GEOMapPolylineImpl(map)
                                    .setPositions(effect.points)
                                    .setLineColor(0x80696969.toInt())
                                    .setLineWidth(3f)
                                    .show()
                            }
                        }
                    }
                }
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventBus(event: CenterToLastLocation) {
        geoaiMapManagerImpl.getMap()?.let {
            it.moveToLocation()
            it.getMapCamera().getZoomLevel().let { zoomLevel ->
                if (zoomLevel < 5) geoaiMapManagerImpl.getMap()?.getMapCamera()?.setZoomLevel(16.0)
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventBus(event: CenterToDroneLocation) {
        mViewModel.aircraftLocation.value?.let {
            geoaiMapManagerImpl.getMap()?.getMapCamera()?.getZoomLevel()?.let { zoomLevel ->
                when {
                    zoomLevel < 5 -> geoaiMapManagerImpl.getMap()?.getMapCamera()?.setPosition(it, 16.0f)
                    else -> geoaiMapManagerImpl.getMap()?.getMapCamera()?.setPosition(it)
                }
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventBus(event: LockCameraByDroneLocation) = event.isLock.also { mViewModel.isLockMapCameraByDroneLocation.value = it }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventBus(event: ChangeMapSource) { geoaiMapManagerImpl.getMap()?.setMapType(SP().getInt(MAP_SOURCE_KEY, 3)) }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventBus(event: ToggleMapSize) {
        when (event.type) {
            ToggleSize.BIG -> mViewModel.sendUiState(MapViewState.MapBigView)
            ToggleSize.MINI -> mViewModel.sendUiState(MapViewState.MapMiniView)
            ToggleSize.ICON -> mViewModel.sendUiState(MapViewState.MapIconView)
        }
    }
}